use std::cmp::Ordering;

pub fn compare_instance(a: &str, b: &str) -> Ordering {
    let mut a_iter = a.chars().peekable();
    let mut b_iter = b.chars().peekable();

    // if a.len() > b.len() {
    //     return Ordering::Greater;
    // }
    // if a.len() < b.len() {
    //     return Ordering::Less;
    // }
    loop {
        match (a_iter.next(), b_iter.next()) {
            (Some(ac), Some(bc)) => {
                if ac.is_digit(10) && bc.is_digit(10) {
                    // Handle number part
                    let num_a = a_iter
                        .by_ref()
                        .take_while(|&c| c.is_digit(10))
                        .collect::<String>()
                        .parse::<u64>()
                        .unwrap_or(0);
                    let num_b = b_iter
                        .by_ref()
                        .take_while(|&c| c.is_digit(10))
                        .collect::<String>()
                        .parse::<u64>()
                        .unwrap_or(0);
                    match num_a.cmp(&num_b) {
                        Ordering::Equal => continue,
                        other => return other,
                    }
                } else if ac != bc {
                    // Handle non-number part
                    return ac.cmp(&bc);
                }
            }
            (None, None) => return Ordering::Equal,
            (Some(_), None) => return Ordering::Greater,
            (None, Some(_)) => return Ordering::Less,
        }
    }
}

pub(crate) fn compare(a: &str, b: &str) -> Ordering {
    // 首先检查两个字符串是否都为空
    if a.is_empty() && b.is_empty() {
        return Ordering::Equal;
    } else if a.is_empty() {
        // 空字符串被认为是小于任何非空字符串
        return Ordering::Less;
    } else if b.is_empty() {
        return Ordering::Greater;
    }

    let a_chars = a.chars().collect::<Vec<char>>();
    let b_chars = b.chars().collect::<Vec<char>>();

    let mut i = 0;
    let mut j = 0;
    let a_length = a_chars.len();
    let b_length = b_chars.len();
    while i < a_length && j < b_length {
        let a_val = a_chars.get(i).unwrap();
        let b_val = b_chars.get(j).unwrap();
        // 检查当前字符是否都是数字
        if is_digit(i, &a_chars) && is_digit(j, &b_chars) {
            let mut num1 = 0;
            let mut num2 = 0;

            // 从当前位置开始，连续读取数字字符
            while i < a_length && is_digit(i, &a_chars) {
                num1 = num1 * 10 + (a_chars.get(i).unwrap().to_digit(10).unwrap() as i32);
                i += 1;
            }
            while j < b_length && is_digit(j, &b_chars) {
                num2 = num2 * 10 + (b_chars.get(j).unwrap().to_digit(10).unwrap() as i32);
                j += 1;
            }

            // 如果两个数字不相等，返回它们的比较结果
            if num1 != num2 {
                return num1.cmp(&num2);
            }
        } else if a_val != b_val {
            // 如果当前字符不相等，返回它们的ASCII码比较结果
            return a_val.cmp(&b_val);
        } else {
            // 如果当前字符相等，移动到下一对字符
            i += 1;
            j += 1;
        }
    }

    // 如果所有对应字符都相等，比较字符串长度
    a.len().cmp(&b.len())
}

fn is_digit(i: usize, a_chars: &Vec<char>) -> bool {
    a_chars.get(i).map_or(false, |c| c.is_digit(10))
}

fn compare2(a: &str, b: &str) -> Ordering {
    if a == b {
        return Ordering::Equal;
    }

    let mut a_chars = a.chars();
    let mut b_chars = b.chars();

    loop {
        let a_val = a_chars.next();
        let b_val = b_chars.next();

        // 如果任一字符串结束，则比较长度
        if a_val.is_none() || b_val.is_none() {
            return a.len().cmp(&b.len());
        }

        let a_val = a_val.unwrap();
        let b_val = b_val.unwrap();

        // 检查是否都是数字并比较
        if let (Some(a_num), Some(b_num)) = (a_val.to_digit(10), b_val.to_digit(10)) {
            let a_num_str = a_chars
                .clone()
                .peekable()
                .take_while(|c: &char| c.is_digit(10))
                .collect::<String>();
            let b_num_str = b_chars
                .clone()
                .peekable()
                .take_while(|c: &char| c.is_digit(10))
                .collect::<String>();
            let num_cmp = a_num_str
                .parse::<i32>()
                .unwrap_or(0)
                .cmp(&b_num_str.parse::<i32>().unwrap_or(0));
            if num_cmp != Ordering::Equal {
                return num_cmp;
            }
            continue;
        }

        // 如果当前字符不相等，返回它们的比较结果
        if a_val != b_val {
            return a_val.cmp(&b_val);
        }
    }
}

#[cfg(test)]
mod tests {
    use crate::extension::index::index::key_comparator::compare2;

    #[test]
    fn key_comparator() {
        let mut strings = vec![
            "103", "101", "102", "1011", "1013", "1021", "1022", "1012", "1023",
        ];
        strings.sort_unstable_by(|&a, &b| compare2(&a, &b));
        assert_eq!(
            strings,
            vec!["101", "102", "103", "1011", "1012", "1013", "1021", "1022", "1023"]
        );

        // 对于reversed()的逻辑，我们通过反转slice然后再次排序实现
        strings.reverse();
        strings.sort_unstable_by(|&a, &b| compare2(&b, &a));
        assert_eq!(
            strings,
            vec!["1023", "1022", "1021", "1013", "1012", "1011", "103", "102", "101"]
        );
    }

    #[test]
    fn key_comparator2() {
        // 测试不同前缀的字符串排序
        let mut strings = vec![
            "moment-101",
            "moment-102",
            "moment-103",
            "moment-1011",
            "moment-1013",
            "moment-1021",
            "moment-1022",
            "moment-1012",
            "moment-1023",
        ];
        strings.sort_by(|a, b| compare2(a, b));
        assert_eq!(
            strings,
            vec![
                "moment-101",
                "moment-102",
                "moment-103",
                "moment-1011",
                "moment-1012",
                "moment-1013",
                "moment-1021",
                "moment-1022",
                "moment-1023"
            ]
        );

        // 测试日期字符串排序
        let mut dates = vec![
            "2022-01-15",
            "2022-02-01",
            "2021-12-25",
            "2022-01-01",
            "2022-01-02",
        ];
        dates.sort_by(|a, b| compare2(a, b));
        assert_eq!(
            dates,
            vec![
                "2021-12-25",
                "2022-01-01",
                "2022-01-02",
                "2022-01-15",
                "2022-02-01"
            ]
        );

        // 测试纯字母字符串排序
        let mut alphabetic_strings = vec!["xyz", "abc", "def", "abcde", "xyzabc"];
        alphabetic_strings.sort_by(|a, b| compare2(a, b));
        assert_eq!(
            alphabetic_strings,
            vec!["abc", "abcde", "def", "xyz", "xyzabc"]
        );

        // 测试空字符串排序
        let mut strings_with_empty = vec!["", "abc", "123", "xyz"];
        strings_with_empty.sort_by(|a, b| compare2(a, b));
        assert_eq!(strings_with_empty, vec!["", "123", "abc", "xyz"]);

        // 测试相同字符串排序
        let mut same_strings = vec!["abc", "abc", "abc", "abc"];
        same_strings.sort_by(|a, b| compare2(a, b));
        assert_eq!(same_strings, vec!["abc", "abc", "abc", "abc"]);

        // Rust中不使用null值，因此这个测试用例不适用
        // 测试包含null元素的排序
        // let mut strings_with_null = vec![null, "abc", "123", "xyz"];
        // strings_with_null.sort_by(|a, b| compare_strings(a, b));
        // assert_eq!(
        //     strings_with_null,
        //     vec!["123", "abc", "xyz", null]
        // );
    }

    #[test]
    fn test_number_and_str() {
        // 测试字母和数字混合的字符串排序
        let mut alphanumeric_strings = vec!["abc123", "abc45", "abc9", "abc100", "abc20"];
        alphanumeric_strings.sort_by(|a, b| compare2(a, b));
        assert_eq!(
            alphanumeric_strings,
            vec!["abc9", "abc20", "abc45", "abc100", "abc123"]
        );
    }
}
